package com.zzhou.entrance.guard.util;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;

import com.zzhou.entrance.guard.AppConfig;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.channels.FileChannel;

/**
 * Created by ZhangTao on 9/1/16.
 */
public class FileUtils {

//    /**
//     * 得到SD卡根目录.
//     */
//    public static File getRootPath(Context context) {
//        if (FileUtils.sdCardIsAvailable()) {
//            return Environment.getExternalStorageDirectory(); // 取得sdcard文件路径
//        } else {
//            return context.getFilesDir();
//        }
//    }

    /**
     * 得到SD卡根目录.
     */
    public static File getRootPath() {
        File path = null;
        if (sdCardIsAvailable()) {
            path = Environment.getExternalStorageDirectory(); // 取得sdcard文件路径
        } else {
            path = Environment.getDataDirectory();
        }
        return path;
    }

    /**
     * SD卡是否可用.
     */
    public static boolean sdCardIsAvailable() {
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File sd = new File(Environment.getExternalStorageDirectory().getPath());
            return sd.canWrite();
        } else
            return false;
    }

    /**
     * 复制文件
     *
     * @param from
     * @param to
     */
    public static void copyFile(File from, File to) {
        if (null == from || !from.exists()) {
            return;
        }
        if (null == to) {
            return;
        }
        FileInputStream is = null;
        FileOutputStream os = null;
        try {
            is = new FileInputStream(from);
            if (!to.exists()) {
                to.createNewFile();
            }
            os = new FileOutputStream(to);
            copyFileFast(is, os);
        } catch (Exception e) {
            throw new RuntimeException(FileUtils.class.getClass().getName(), e);
        } finally {
            closeIO(is, os);
        }
    }

    /**
     * 快速复制文件（采用nio操作）
     *
     * @param is 数据来源
     * @param os 数据目标
     * @throws IOException
     */
    public static void copyFileFast(FileInputStream is, FileOutputStream os)
            throws IOException {
        FileChannel in = is.getChannel();
        FileChannel out = os.getChannel();
        in.transferTo(0, in.size(), out);
    }

    /**
     * 关闭流
     */
    public static void closeIO(Closeable... closeables) {
        if (null == closeables || closeables.length <= 0) {
            return;
        }
        for (Closeable cb : closeables) {
            try {
                if (null == cb) {
                    continue;
                }
                cb.close();
            } catch (IOException e) {
                throw new RuntimeException(
                        FileUtils.class.getClass().getName(), e);
            }
        }
    }

    /**
     * 文件或者文件夹是否存在.
     */
    public static boolean fileExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }

    public static void deleteFile(String path) {
        deleteFile(new File(path));
    }

    public static void deleteFile(File file) {
        if (file != null && file.exists())
            file.delete();
    }

    /**
     * 删除指定文件夹下所有文件, 保留文件夹.
     */
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (file.isFile()) {
            file.delete();
            return true;
        }
        File[] files = file.listFiles();
        for (int i = 0; i < files.length; i++) {
            File exeFile = files[i];
            if (exeFile.isDirectory()) {
                delAllFile(exeFile.getAbsolutePath());
            } else {
                exeFile.delete();
            }
        }
        return flag;
    }

    /**
     * 获取指定目录下文件的数量
     * @param filepath
     * @return
     */
    public  static int AllFileNum(String filepath){
        File filelist = new File(filepath);
        int filesNum = filelist.listFiles().length;
        return filesNum;
    }

    /**
     * 文件复制.
     */
    public static boolean copy(String srcFile, String destFile) {
        try {
            FileInputStream in = new FileInputStream(srcFile);
            FileOutputStream out = new FileOutputStream(destFile);
            byte[] bytes = new byte[1024];
            int c;
            while ((c = in.read(bytes)) != -1) {
                out.write(bytes, 0, c);
            }
            in.close();
            out.flush();
            out.close();
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 复制整个文件夹内.
     *
     * @param oldPath string 原文件路径如：c:/fqf.
     * @param newPath string 复制后路径如：f:/fqf/ff.
     */
    public static void copyFolder(String oldPath, String newPath) {
        try {
            (new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);
                    FileOutputStream output = new FileOutputStream(newPath + "/" + (temp.getName()).toString());
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if (temp.isDirectory()) {// 如果是子文件夹
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (NullPointerException e) {
        } catch (Exception e) {
        }
    }

    /**
     * 重命名文件.
     */
    public static boolean renameFile(String resFilePath, String newFilePath) {
        File resFile = new File(resFilePath);
        File newFile = new File(newFilePath);
        return resFile.renameTo(newFile);
    }

    /**
     * 获取磁盘可用空间.
     */
    @SuppressWarnings("deprecation")
    @SuppressLint("NewApi")
    public static long getSDCardAvailaleSize() {
        File path = getRootPath();
        StatFs stat = new StatFs(path.getPath());
        long blockSize, availableBlocks;
        if (Build.VERSION.SDK_INT >= 18) {
            blockSize = stat.getBlockSizeLong();
            availableBlocks = stat.getAvailableBlocksLong();
        } else {
            blockSize = stat.getBlockSize();
            availableBlocks = stat.getAvailableBlocks();
        }
        return availableBlocks * blockSize;
    }

    /**
     * 获取某个目录可用大小.
     */
    @SuppressLint("NewApi")
    @SuppressWarnings("deprecation")
    public static long getDirSize(String path) {
        StatFs stat = new StatFs(path);
        long blockSize, availableBlocks;
        if (Build.VERSION.SDK_INT >= 18) {
            blockSize = stat.getBlockSizeLong();
            availableBlocks = stat.getAvailableBlocksLong();
        } else {
            blockSize = stat.getBlockSize();
            availableBlocks = stat.getAvailableBlocks();
        }
        return availableBlocks * blockSize;
    }

    /**
     * 获取文件或者文件夹大小.
     */
    public static long getFileAllSize(String path) {
        File file = new File(path);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] childrens = file.listFiles();
                long size = 0;
                for (File f : childrens) {
                    size += getFileAllSize(f.getPath());
                }
                return size;
            } else {
                return file.length();
            }
        } else {
            return 0;
        }
    }

    /**
     * 创建一个文件.
     */
    public static boolean initFile(String path) {
        boolean result = false;
        try {
            File file = new File(path);
            if (!file.exists()) {
                result = file.createNewFile();
            } else if (file.isDirectory()) {
                file.delete();
                result = file.createNewFile();
            } else if (file.exists()) {
                result = true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 创建一个文件夹.
     */
    public static boolean initDirectory(String path) {
        boolean result = false;
        File file = new File(path);
        if (!file.exists()) {
            result = file.mkdir();
            LogUtils.e("file un exists() result = " + result);
        } else if (!file.isDirectory()) {
            file.delete();
            result = file.mkdir();
            LogUtils.e("file un isDirectory() result = " + result);
        } else if (file.exists()) {
            result = true;
            LogUtils.e("file exists result = " + result);
        }
        return result;
    }

    /**
     * 创建一个文件夹并返回文件地址
     *
     * @param name
     * @return
     */
    public static String getDir(String dir, String name) {
        StringBuilder sb = new StringBuilder();
        sb.append(dir);
        sb.append(name);
        sb.append(File.separator);
        String path = sb.toString();
        if (initDirectory(path)) {
            return path;
        } else {
            return null;
        }
    }

    /**
     * 复制文件.
     */
    public static long copyFile(InputStream from, File to) throws IOException {
        long totalBytes = 0;
        FileOutputStream fos = new FileOutputStream(to, false);
        try {
            byte[] data = new byte[1024];
            int len;
            while ((len = from.read(data)) > -1) {
                fos.write(data, 0, len);
                totalBytes += len;
            }
            fos.flush();
        } finally {
            fos.close();
        }
        return totalBytes;
    }

    /**
     * 保存流到文件.
     */
    public static void saveFile(InputStream inputStream, String filePath) {
        try {
            OutputStream outputStream = new FileOutputStream(new File(filePath), false);
            int len;
            byte[] buffer = new byte[1024];
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static File saveBitmap(Bitmap bitmap, String path) {
        File file = new File(path);
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }

    /**
     * 用UTF8保存一个文件.
     */
    public static void saveFileUTF8(String path, String content, Boolean append) throws IOException {
        FileOutputStream fos = new FileOutputStream(path, append);
        Writer out = new OutputStreamWriter(fos, "UTF-8");
        out.write(content);
        out.flush();
        out.close();
        fos.flush();
        fos.close();
    }

    /**
     * 用UTF8读取一个文件.
     */
    public static String getFileUTF8(String path) {
        String result = "";
        InputStream fin = null;
        try {
            fin = new FileInputStream(path);
            int length = fin.available();
            byte[] buffer = new byte[length];
            fin.read(buffer);
            fin.close();
            result = new String(buffer, "UTF-8");
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 得到一个文件Intent.
     */
    public static Intent getFileIntent(String path, String mimeType) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(new File(path)), mimeType);
        return intent;
    }

    public static InputStream makeInputBuffered(InputStream inputStream) {
        if (inputStream instanceof BufferedInputStream) {
            return inputStream;
        } else {
            return new BufferedInputStream(inputStream);
        }

    }

    public static OutputStream makeOutputBuffered(OutputStream outputStream) {
        if (outputStream instanceof BufferedOutputStream) {
            return outputStream;
        } else {
            return new BufferedOutputStream(outputStream);
        }

    }

    /**
     * 获取一个对象，把文件转化为对象
     *
     * @param filepath 文件地址
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Object loadObject(String filepath) throws IOException,
            ClassNotFoundException {
        if (doesExisted(new File(filepath))) {
            return loadObject(new FileInputStream(filepath));
        }
        return null;
    }

    /**
     * 获取一个对象，把文件转化为对象
     *
     * @param inputStream
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Object loadObject(InputStream inputStream)
            throws IOException, ClassNotFoundException {
        ObjectInputStream in = new ObjectInputStream(
                makeInputBuffered(inputStream));
        Object object = null;

        object = in.readObject();
        in.close();

        return object;
    }

    /**
     * 判断文件是否存在
     *
     * @param dir
     * @param filename
     * @return
     */
    public static boolean doesExisted(String dir, String filename) {
        boolean exited = false;
        try {

            exited = doesExisted(new File(dir, filename));

        } catch (Exception e) {
        }

        return exited;

    }

    /**
     * 判断文件是否存在
     *
     * @param file
     * @return
     */
    public static boolean doesExisted(File file) {
        if (file != null && file.exists()) {
            return true;
        } else {
            return false;
        }

    }

    /**
     * 把对象保存到文件中
     *
     * @param object
     * @param filepath
     * @throws IOException
     */
    public static void saveObject(Object object, String filepath)
            throws IOException {
        File fileDir = new File(AppConfig.getInstance().APP_PATH_ROOT);
        if (!fileDir.exists()) {
            IOUtils.createFolder(fileDir);
        }
        File file = new File(filepath);
        if (!file.exists()) {
            IOUtils.createFile(filepath);
        }
        FileOutputStream fileOutputStream = new FileOutputStream(filepath);
        saveObject(object, fileOutputStream);
    }

    /**
     * 把对象保存到文件中
     *
     * @param object
     * @param outputStream
     * @throws IOException
     */
    public static void saveObject(Object object, OutputStream outputStream)
            throws IOException {
        ObjectOutputStream out = new ObjectOutputStream(
                makeOutputBuffered(outputStream));
        out.writeObject(object);
        out.close();
    }

    public static String getfileinfo(String data) {
        String filename[] = data.split("/");
        if (filename != null) {
            return filename[filename.length - 2];
        }
        return null;
    }

    /**
     * 获取下载链接文件名
     *
     * @param path
     * @return
     */
    public static String getFileNameWithExtension(String path) {
        int slashIndex = path.lastIndexOf('/');
        String filenameWithExtension;
        filenameWithExtension = path.substring(slashIndex + 1);
        return filenameWithExtension;
    }
}
